using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

namespace System.Web.Core
{
    public class UserManager
    {
        private static EntityEngine entityEngine = new EntityEngine();

        public static User GetAnonymousUser()
        {
            User user = Activator.CreateInstance(Configuration.Instance.UserType) as User;
            user.SetRoles(Configuration.Instance.AnonymousDefaultRoleList);
            user.UserIdentity = new UserIdentity(user.MemberId.Value.ToString(), "CustomAuthentication");
            return user;
        }
        public static User GetUser(UserRequest request)
        {
            return GetUser(RequestHelper.BuildGetUserRequest(request));
        }
        public static User GetUser(Guid memberId)
        {
            return GetUser(RequestHelper.BuildGetUserRequest(memberId));
        }
        public static User GetUser(int userId)
        {
            return GetUser(RequestHelper.BuildGetUserRequest(userId));
        }
        public static EntityList GetUserList(UserListRequest request)
        {
            return entityEngine.ExecuteRequest(RequestHelper.BuildGetUserListRequest(request)).Reply as EntityList;
        }
        public static int CreateUser(User user)
        {
            return entityEngine.ExecuteRequest(RequestHelper.BuildAddUserRequest(user)).Status;
        }
        public static int UpdateUser(User user)
        {
            return entityEngine.ExecuteRequest(RequestHelper.BuildUpdateUserRequest(user)).Status;
        }
        public static int DeleteUser(int userId)
        {
            return entityEngine.ExecuteRequest(RequestHelper.BuildDeleteUserRequest(userId)).Status;
        }

        public static void CreateUserDefaultRoles(int userId)
        {
            foreach (Role role in Configuration.Instance.RegisteredDefaultRoleList)
            {
                RoleManager.AddUserToRole(userId, role.EntityId.Value);
            }
        }
        public static void CreateUserDefaultRoles(User user)
        {
            foreach (Role role in Configuration.Instance.RegisteredDefaultRoleList)
            {
                RoleManager.AddUserToRole(user.EntityId.Value, role.EntityId.Value);
            }
        }
        public static EntityList GetRoleUsers(int roleId)
        {
            return entityEngine.ExecuteRequest(RequestHelper.BuildGetRoleUsersRequest(roleId)).Reply as EntityList;
        }

        public static Avatar GetUserAvatar(User user)
        {
            if (user.AvatarContent.Value != null && user.AvatarContent.Value.Length > 0)
            {
                Avatar avatar = new Avatar();
                avatar.FileName = user.AvatarFileName.Value;
                avatar.Content = user.AvatarContent.Value;
                return avatar;
            }
            else
            {
                return GetUserDefaultAvatar();
            }
        }
        public static Avatar GetUserDefaultAvatar()
        {
            string file = Globals.MapPath(Configuration.Instance.UserDefaultAvatarPath);
            if (!File.Exists(file))
            {
                return null;
            }
            Stream stream = GetUserAvatarStream(file, 150, 150);
            if (stream != null)
            {
                return new Avatar(ResizeImage(stream, 150, 150));
            }
            return null;
        }
        public static void UpdateUserAvatar(User user, HttpPostedFile postedFile)
        {
            if (user == null || postedFile == null || postedFile.InputStream == null)
            {
                return;
            }

            Avatar avatar = new Avatar(ResizeImage(postedFile.InputStream, 150, 150));

            user.AvatarFileName.Value = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf("\\") + 1);
            user.AvatarContent.Value = avatar.Content;

            UpdateUser(user);
        }
        public static void UpdateUserAvatar(User user, Stream stream)
        {
            if (user == null || stream == null)
            {
                return;
            }

            Avatar avatar = new Avatar(ResizeImage(stream, 150, 150));

            user.AvatarFileName.Value = null;
            user.AvatarContent.Value = avatar.Content;

            UpdateUser(user);
        }
        public static void DeleteUserAvatar(User user)
        {
            user.AvatarFileName.Value = null;
            user.AvatarContent.Value = null;

            UpdateUser(user);
        }

        private static MemoryStream GetUserAvatarStream(string file, int height, int width)
        {
            MemoryStream returnStream = new MemoryStream();
            Image image = Image.FromFile(file);
            Size newSize = Globals.GetNewSize(width, height, image.Width, image.Height);
            Bitmap outBitmap = new Bitmap(newSize.Width, newSize.Height);
            Graphics g = Graphics.FromImage(outBitmap);

            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.DrawImage(image, new Rectangle(0, 0, newSize.Width, newSize.Height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);

            g.Dispose();

            EncoderParameters encoderParams = new EncoderParameters();
            long[] quality = new long[1];

            quality[0] = 100;

            EncoderParameter encoderParameter = new EncoderParameter(Encoder.Quality, quality);

            encoderParams.Param[0] = encoderParameter;

            ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();

            ImageCodecInfo jpegICI = null;

            for (int i = 0; i < arrayICI.Length; i++)
            {
                if (arrayICI[i].FormatDescription.Equals("JPEG"))
                {
                    jpegICI = arrayICI[i];
                    break;
                }
            }

            if (jpegICI != null)
            {
                outBitmap.Save(returnStream, jpegICI, encoderParams);
            }
            else
            {
                outBitmap.Save(returnStream, image.RawFormat);
            }

            return returnStream;
        }
        private static MemoryStream ResizeImage(Stream stream, int height, int width)
        {
            MemoryStream returnStream = new MemoryStream();
            Image image = Image.FromStream(stream);
            Size newSize = Globals.GetNewSize(width, height, image.Width, image.Height);
            Bitmap outBitmap = new Bitmap(newSize.Width, newSize.Height);
            Graphics g = Graphics.FromImage(outBitmap);

            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.DrawImage(image, new Rectangle(0, 0, newSize.Width, newSize.Height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);

            g.Dispose();

            outBitmap.Save(returnStream, image.RawFormat);

            return returnStream;

        }
        private static void InitializeUser(User user)
        {
            if (user != null)
            {
                user.SetRoles(RoleManager.GetUserRoles(user.EntityId.Value));
                user.UserIdentity = new UserIdentity(user.MemberId.Value.ToString(), "CustomAuthentication");
            }
        }
        private static User GetUser(BaseRequestBinder requestBinder)
        {
            User user = entityEngine.ExecuteRequest(requestBinder).Reply as User;
            InitializeUser(user);
            return user;
        }
    }
}